/*
 * Copyright (C) 2009 Leandro Aparecido <lehphyro@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.metalframework.jsf.validation;

import java.util.*;

import javax.faces.application.*;
import javax.faces.component.*;
import javax.faces.context.*;
import javax.validation.*;

import org.metalframework.annotation.*;
import org.metalframework.util.*;
import org.metalframework.validation.*;
import org.slf4j.*;

@InfrastructureComponent
public class FacesConstraintViolationHandler implements ConstraintViolationHandler {

	private static final Logger logger = LoggerFactory.getLogger(FacesConstraintViolationHandler.class);
	
	public void handle(Set<ConstraintViolation<Object>> violations) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		
		if (facesContext != null) {
			for (ConstraintViolation<Object> violation : violations) {
				String clientId;
				
				UIComponent component = FacesUtils.findComponentByPropertyName(getPropertyNameFromPath(violation.getPropertyPath()));
				if (component == null) {
					logger.warn("Could not find a component for property [{}]", violation.getPropertyPath());
					clientId = getPropertyNameFromPath(violation.getPropertyPath());
				} else {
					clientId = component.getClientId(facesContext);
				}
				
				FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, violation.getMessage(), null);
				facesContext.addMessage(clientId, msg);
			}
		}
	}

	protected String getPropertyNameFromPath(Path path) {
		String name = null;
		for (Path.Node node : path) {
			name = node.getName();
		}
		return name;
	}

}
